package com.surfilter.code.gen.tool;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.apache.tools.ant.Task;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;

import com.surfilter.code.model.Field;
import com.surfilter.code.model.GenService;
import com.surfilter.code.model.ModuleModel;
import com.surfilter.code.model.PK;
import com.surfilter.code.util.DaoTools;
import com.surfilter.code.util.StringUtils;

public class CodeGenTools {

	private String dataSource;
    
    private String jsPrefix;
    
    private String jsModPath;
    
    private String pattern;

    private String javaModPath;

    private String pkg;

    private boolean isCover;
    
    private String dialet;
	    
    private static String JS_CONTROLLER_TEMPLATE = "com/surfilter/code/gen/template/jsController.vm";
        
    private static String JS_MODEL_TEMPLATE = "com/surfilter/code/gen/template/jsModel.vm";
    
    private static String JS_STORE_TEMPLATE = "com/surfilter/code/gen/template/jsStore.vm";
    
    private static String JS_VIEW_TEMPLATE = "com/surfilter/code/gen/template/jsViewContainer.vm";
    
    private static String JS_MODULE_TEMPLATE = "com/surfilter/code/gen/template/jsModule.vm";
    
    private static String JAVA_DAO_TEMPLATE = "com/surfilter/code/gen/template/javaDao.vm";
    
    private static String JAVA_SERVICE_IMPL_TEMPLATE = "com/surfilter/code/gen/template/javaServiceImpl.vm";
    
    private static String JAVA_SERVICE_INTERFACE_TEMPLATE = "com/surfilter/code/gen/template/javaServiceInterface.vm";
    
    private static String JAVA_MODEL_TEMPLATE = "com/surfilter/code/gen/template/javaModel.vm";
    
    private static String MYSQL_TEMPLATE = "com/surfilter/code/gen/template/mysql.vm";
    
    private static String ORACLE_TEMPLATE = "com/surfilter/code/gen/template/oracle.vm";
    
    
    
	public CodeGenTools(){
		init();
	}
	
	public CodeGenTools(String dataSource, String jsPrefix, String jsModPath,
			String pattern, String javaModPath, String pkg) {
		this(dataSource, jsPrefix, jsModPath, pattern, javaModPath, pkg, false,"mysql");
	}

	public CodeGenTools(String dataSource, String jsPrefix, String jsModPath,
			String pattern, String javaModPath, String pkg, boolean isCover,String dialet) {
		this.dataSource = dataSource;
		this.jsPrefix = jsPrefix;
		this.jsModPath = jsModPath;
		this.pattern = pattern;
		this.javaModPath = javaModPath;
		this.pkg = pkg;
		this.isCover = isCover;
		this.dialet = dialet;
		init();
		initVelocity();
	}
	
	/**
	 * 初始化Velocity
	 */
	private void initVelocity() {
		Properties pros=new Properties();
        pros.put("input.encoding","UTF-8");
        pros.put("output.encoding","UTF-8");
        pros.put("resource.loader","classpath");
        pros.put("classpath.resource.loader.description","Velocity File ClassPath Resource Loader");
        pros.put("classpath.resource.loader.class","org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); 
        try {
            Velocity.init(pros);
        } catch (Exception e) {
            throw new RuntimeException("velocity init error");
        }
	}

	private void init() {
		try {
			DaoTools daoTools = DaoTools.getInstance();
			//初始化数据库连接
			daoTools.initConnection(dataSource);
			//获得所有模块信息
			moduleList = daoTools.getModuleListByPattens(pattern);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private List<ModuleModel> moduleList = new ArrayList<ModuleModel>();

		
	/**
	 * 生成Js controller
	 * @throws Exception 
	 * @throws ParseErrorException 
	 * @throws ResourceNotFoundException 
	 */
	public void genJsController(ModuleModel module) throws Exception{
		//js文件类名
		String jsClassName = getJsClassName(module, "controller");
		
		//Js ViewClassName
		String viewClassName = getJsClassName(module, "view");
		
		//js文件路径
		String jsFileLocate = getJsFileAbsName(module, "controller");
		
		//model名集合
		List<String> modelClassNameList = getJsClassNameList(module,"model");
		List<String> storeClassNameList = getJsClassNameList(module,"store");
		Template template = Velocity.getTemplate(JS_CONTROLLER_TEMPLATE);
		VelocityContext context = new VelocityContext();
		context.put("jsClassName", jsClassName);
		context.put("storeClassNameList", storeClassNameList);
		context.put("modelClassNameList", modelClassNameList);
		context.put("viewClassName", viewClassName);
		
		FileWriter fileWriter = new FileWriter(jsFileLocate.toString());
		template.merge(context, fileWriter);
		fileWriter.close();
	}
	
	private List<String> getJsClassNameList(ModuleModel module,String part) {
		List<String> target = new ArrayList<String>();
		
		String tableNames = module.getTableName();
		if(tableNames == null || tableNames.trim().equals("")){
			return target;
		}
		String[] tableNameArray = tableNames.split(",");
		for(String tableName : tableNameArray){
			target.add(getJsClassName(module, tableName, part));
			
		}
		return target;
	}

	/**
	 * 将字段的类型转为JS类型
	 * @param fieldList
	 */
	private void convertFieldListTypeToJsType(List<Field> fieldList) {
		for(Field field : fieldList){
			String type = field.getType();
			String[] typeSub = type.split("\\.");
			if(typeSub.length == 0){
				continue;
			}
			String last = typeSub[typeSub.length - 1];
			if(last.toLowerCase().equals("string")){
				field.setType("string");
			}else if(last.toLowerCase().equals("integer")){
				field.setType("int");
			}else if(last.toLowerCase().equals("timestamp") || last.toLowerCase().equals("date")){
				field.setType("date");
			}else if(last.toLowerCase().equals("long")){
				field.setType("int");
			}
		}
	}

	/**
	 * 生成模块入口类
	 * @throws Exception 
	 * @throws ParseErrorException 
	 * @throws ResourceNotFoundException 
	 */
	public void genJsModule(ModuleModel module) throws Exception {
		
		String jsClassName = getJsModuleClassName(module);
		
		String viewClassName = getJsClassName(module, "view");
		
		String containerClassName = getJsClassName(module,"controller");
		
		String jsFileLocate = getJsModuleName(module, "module");
		
		Template template = Velocity.getTemplate(JS_MODULE_TEMPLATE);
		VelocityContext context = new VelocityContext();
		context.put("jsClassName", jsClassName);		
		context.put("viewClassName", viewClassName);
		context.put("containerClassName", containerClassName);
		FileWriter fileWriter = new FileWriter(jsFileLocate.toString());
		
		template.merge(context, fileWriter);
		fileWriter.close();
	}

	/**
	 * 生成其他目录
	 */
	public void genJsDirs(ModuleModel module) {
		createJsFilePath(module, "module");
		createJsFilePath(module, "view");
		createJsFilePath(module, "store");
		createJsFilePath(module, "model");
		createJsFilePath(module, "controller");
//		createJsFilePath(module, "css");
//		createJsFilePath(module, "images");		
	}
	/**
	 * js model
	 */
	private void genJsModel(ModuleModel module) throws Exception {
		String tableNames = module.getTableName();
		if(tableNames == null || tableNames.trim().equals("")){
			return;
		}
		String[] tableNameArray = tableNames.split(",");
		for(String tableName : tableNameArray){
			
			String[] tableArray = tableName.split(":");
			String ds = dataSource;
			
			if(tableArray.length == 2){
				ds = tableArray[0];
				tableName = tableArray[1];
			}
			
			if(tableName.trim().equals("")){
				continue;
			}
			
			//js文件类名
			String jsClassName = getJsClassName(module, tableName, "model");
			
			//js文件路径
			String folderPath = createJsFilePath(module, "model");
			
			//js文件名
			String fileName = StringUtils.convertTableNameToClazzName(tableName) + StringUtils.convertFirstCharUpperCap("model");
			
			//js文件ID
			String jsClassId = getJsClassId(module, tableName, "model");
			
			//获取指定表的列信息集合
			List<Field> fieldList = convertFieldList(DaoTools.getInstance().getFieldList(tableName, ds));
			
			convertFieldListTypeToJsType(fieldList);
			
			Template template = Velocity.getTemplate(JS_MODEL_TEMPLATE);
			VelocityContext context = new VelocityContext();
			context.put("fieldList", fieldList);
			
			context.put("jsClassName", jsClassName);
			context.put("jsClassId", jsClassId);
			
			FileWriter fileWriter = new FileWriter(folderPath + "/" + fileName + ".js");
			
			template.merge(context, fileWriter);
			fileWriter.close();
		}
	}

	/**
	 * 生成store
	 * @param module
	 * @throws IOException 
	 * @throws MethodInvocationException 
	 * @throws ParseErrorException 
	 * @throws ResourceNotFoundException 
	 */
	private void genJsStore(ModuleModel module) throws Exception {

		String tableNames = module.getTableName();
		if(tableNames == null || tableNames.trim().equals("")){
			return;
		}
		String[] tableNameArray = tableNames.split(",");
		for(String tableName : tableNameArray){
			
			//js文件类名
			String jsClassName = getJsClassName(module, tableName, "store");
			
			//model类名
			String modelClassName = getJsClassName(module, tableName, "model");
			
			//js文件路径
			String foldePath = createJsFilePath(module, "store");
			
			String fileName = StringUtils.convertTableNameToClazzName(tableName) + StringUtils.convertFirstCharUpperCap("store");
			
			//js文件ID
			String jsClassId = getJsClassId(module, tableName, "store");
			
			Template template = Velocity.getTemplate(JS_STORE_TEMPLATE);
			
			VelocityContext context = new VelocityContext();
			context.put("jsClassName", jsClassName);
			context.put("jsClassId", jsClassId);
			context.put("modelClassName", modelClassName);
			context.put("moduleName", module.getModuleName());
			context.put("methodSubName", getJavaJsClassName(tableName, ""));
			
			FileWriter fileWriter = new FileWriter(foldePath + "/" + fileName + ".js");
			
			template.merge(context, fileWriter);
			fileWriter.close();}
	}

	/**
	 * 创建并返回JAVA文件夹路径
	 * @param module
	 * @param string
	 * @return
	 */
	private String createJavaFolderPath(ModuleModel module, String part) {
		StringBuffer target = new StringBuffer();
		target.append(javaModPath);
		target.append("/");
		String pkgPath = StringUtils.convertStringReplacePointToSplash(pkg);
		target.append(pkgPath);
		target.append("/");
		String midFilePath = StringUtils.convertStringReplacePointToSplash(module.getCodePath());

		target.append(midFilePath);
		
		target.append("/");
		
		target.append(part);

		createFolder(target.toString());
		
		return target.toString();
	}

	/**
	 * 生成JAVA数据模型
	 * @param module
	 * @exception Exception
	 */
	private void genJavaModel(ModuleModel module) throws Exception {
		String tableNames = module.getTableName();
		if(tableNames == null || tableNames.trim().equals("")){
			return;
		}
		String[] tableNameArray = tableNames.split(",");
		for(String tableName : tableNameArray){
			
			String[] tableArray = tableName.split(":");
			String ds = dataSource;
			
			if(tableArray.length == 2){
				ds = tableArray[0];
				tableName = tableArray[1];
			}
			
			if(tableName.trim().equals("")){
				continue;
			}
			//文件类名
			String modelClassName = getJavaJsClassName(tableName, "model");
			
			//文件夹路径
			String filePath = createJavaFolderPath(module, "model");
			
			//获取指定表的列信息集合
			List<Field> fieldList = convertFieldList(DaoTools.getInstance().getFieldList(tableName, ds));
			
			//package Name
			String pkgName = getJavaPkgName(module, "model");
			
			Template template = Velocity.getTemplate(JAVA_MODEL_TEMPLATE);
			VelocityContext context = new VelocityContext();
			context.put("modelClassName", modelClassName);
			context.put("fieldList", fieldList);
			context.put("pkgName", pkgName);
			
			FileWriter fileWriter = new FileWriter(filePath + "/" + modelClassName + ".java");
			template.merge(context, fileWriter);
			fileWriter.close();
		}
	}

	/**
	 * 转换fieldList将其中name字段改为java命名规则
	 * @param fieldList
	 * @return
	 */
	private List<Field> convertFieldList(List<Field> fieldList) {
		
		for(Field field : fieldList){
			field.setName(StringUtils.convertColumNameToJavaFieldName(field.getName()));
		}
		return fieldList;
	}
	
	/**
	 * 生成服务类及接口
	 * @throws SQLException 
	 */
	public void genJavaService(ModuleModel module) throws Exception {
		String serviceName = module.getServiceName();
		
		String tableNames = module.getTableName();
		
		//服务实现类类名
		String serviceImplClassName = StringUtils.convertFirstCharUpperCapOnly(serviceName) + StringUtils.convertFirstCharUpperCapOnly("impl");
		
		//服务接口名
		String serviceInterfaceClassName = StringUtils.convertFirstCharUpperCapOnly(serviceName) ;
		
		//文件夹路径
		String fileImplPath = createJavaFolderPath(module, "service/impl");
		String fileInterfacePath = createJavaFolderPath(module, "service");
		
		//Dao名集合
		List<String> daoClassList = getClassListByTableName(tableNames, "dao");
		
		//模型名集合
		List<String> modelClassList = getClassListByTableName(tableNames, "model");
		
		List<PK> pkList = getPKListByTableName(tableNames);
		
		//服务集合
		List<GenService> serviceList = getServiceListByTableName(tableNames);
		
		
		
		//package name
		String pkgImplName = getJavaPkgName(module, "service.impl");
		
		String pkgInterfaceName = getJavaPkgName(module, "service");
		
		//import list
		List<String> interfaceImportList = new ArrayList<String>();
		for(String modelClass : modelClassList){
			interfaceImportList.add(getJavaPkgName(module, "model") + "." + modelClass);
		}
		
		List<String> implImportList = new ArrayList<String>();
		implImportList.addAll(interfaceImportList);
		
		for(String daoClass : daoClassList){
			implImportList.add(getJavaPkgName(module, "dao") + "." + daoClass);
		}
		
		Template templateImpl = Velocity.getTemplate(JAVA_SERVICE_IMPL_TEMPLATE);
		
		Template templateInterface = Velocity.getTemplate(JAVA_SERVICE_INTERFACE_TEMPLATE);
		
		VelocityContext context = new VelocityContext();
		
		context.put("className", serviceImplClassName);
		context.put("interfaceName", serviceInterfaceClassName);
		
		//注解
		context.put("serviceName", serviceName);
		
		context.put("serviceList", serviceList);
		
		context.put("pkList", pkList);
		
		context.put("pkgImplName", pkgImplName);
		context.put("pkgInterfaceName", pkgInterfaceName);
		
		context.put("implImportList", implImportList);
		context.put("interfaceImportList", interfaceImportList);
		
		FileWriter fileWriterImpl = new FileWriter(fileImplPath + "/" + serviceImplClassName + ".java");
		
		FileWriter fileWriterInterface = new FileWriter(fileInterfacePath + "/" + serviceInterfaceClassName + ".java");
		
		templateImpl.merge(context, fileWriterImpl);
		templateInterface.merge(context, fileWriterInterface);
		
		fileWriterImpl.close();
		fileWriterInterface.close();
	}

	/**
	 * @param tableNames
	 * @return
	 */
	private List<PK> getPKListByTableName(String tableNames) {
		List<PK> target = new ArrayList<PK>();
		String[] tableNameArray = tableNames.split(",");
		for (String tableName : tableNameArray) {
			try {
				target.add(DaoTools.getInstance().getPkByTableName(tableName, dataSource));
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return target;
	}

	private List<GenService> getServiceListByTableName(String tableNames) {

		List<GenService> target = new ArrayList<GenService>();
		
		if(tableNames == null || tableNames.trim().equals("")){
			return target;
		}
		String[] tableNameArray = tableNames.split(",");
		
		for(String tableName : tableNameArray){
			GenService genService = new GenService();
			genService.setDaoClassName(getJavaJsClassName(tableName, "dao"));
			genService.setModelClassName(getJavaJsClassName(tableName, "model"));
			genService.setMethodMidName(getJavaJsClassName(tableName, ""));
			target.add(genService);
		}
		return target;
	}

	/**
	 * 获取服务类的Dao集合
	 * @param tableNames
	 * @return
	 */
	private List<String> getClassListByTableName(String tableNames, String part) {
		
		List<String> target = new ArrayList<String>();
		
		if(tableNames == null || tableNames.trim().equals("")){
			return target;
		}
		String[] tableNameArray = tableNames.split(",");
		
		for(String tableName : tableNameArray){
			target.add(getJavaJsClassName(tableName, part));
		}
		return target;
	}
	
	/**
	 * 为指定模块生成sqlxml
	 * @param module
	 * @throws Exception 
	 * @throws ParseErrorException 
	 * @throws ResourceNotFoundException 
	 */
	private void genJavaSqlXml(ModuleModel module) throws Exception {
		String tableNames = module.getTableName();
		if(tableNames == null || tableNames.trim().equals("")){
			return;
		}
		String[] tableNameArray = tableNames.split(",");
		for(String tableName : tableNameArray){
			
			String[] tableArray = tableName.split(":");
			String ds = dataSource;
			
			if(tableArray.length == 2){
				ds = tableArray[0];
				tableName = tableArray[1];
			}
			
			if(tableName.trim().equals("")){
				continue;
			}
			
			//文件类名
			String fileName = getJavaJsClassName(tableName, "");
			
			//文件夹路径
			String filePath = createJavaFolderPath(module, "config/sqlxml");
			
			//model名
			String modelClassName = getJavaJsClassName(tableName, "model");
			
			//包名
			String pkgName = getJavaPkgName(module, "model");
			
			//表列名集合
			List<String> tableColumList = getTableColumList(tableName);
			
			//java字段名集合
			List<String> javaFieldList = getJavaFieldList(tableName);
			
			//主键
			PK pk = DaoTools.getInstance().getPkByTableName(tableName, ds);
			
			convertFieldList(pk.getCols());
			
			String vm = this.dialet.equals("mysql")? MYSQL_TEMPLATE : ORACLE_TEMPLATE;
			
			Template template = Velocity.getTemplate(vm);
			VelocityContext context = new VelocityContext();
			
			context.put("pkgName", pkgName);
			context.put("modelClassName", modelClassName);
			context.put("tableName", tableName);
			context.put("tableColumList", tableColumList);
			context.put("javaFieldList", javaFieldList);
			context.put("pk", pk);
			context.put("methodSubName", getJavaJsClassName(tableName, ""));
			
			FileWriter fileWriter = new FileWriter(filePath + "/" + fileName + ".xml");
			template.merge(context, fileWriter);
			fileWriter.close();
		}
	}


	/**
	 * 获取JavaField名
	 * @param tableName
	 * @return
	 * @throws SQLException
	 * @throws ClassNotFoundException 
	 */
	private List<String> getJavaFieldList(String tableName) throws SQLException, ClassNotFoundException {
		
		String[] tableArray = tableName.split(":");
		String ds = dataSource;
		
		if(tableArray.length == 2){
			ds = tableArray[0];
			tableName = tableArray[1];
		}
		
		if(tableName.trim().equals("")){
			return null;
		}
		
		List<Field> fieldList = DaoTools.getInstance().getFieldList(tableName, ds);
		List<String> target = new ArrayList<String>();
		for(Field field : fieldList){
			target.add(StringUtils.convertColumNameToJavaFieldName(field.getName()));
		}
		
		return target;
	}

	/**
	 * 获取表列名集合
	 * @return
	 * @throws SQLException 
	 * @throws ClassNotFoundException 
	 */
	private List<String> getTableColumList(String tableName) throws SQLException, ClassNotFoundException {
		
		String[] tableArray = tableName.split(":");
		String ds = dataSource;
		
		if(tableArray.length == 2){
			ds = tableArray[0];
			tableName = tableArray[1];
		}
		
		if(tableName.trim().equals("")){
			return null;
		}
		
		List<Field> fieldList = DaoTools.getInstance().getFieldList(tableName, ds);
		List<String> target = new ArrayList<String>();
		for(Field field : fieldList){
			target.add(field.getName().toUpperCase());
		}
		return target;
	}

	/**
	 * 获取指定的包名
	 * @param module
	 * @return
	 */
	private String getJavaPkgName(ModuleModel module, String part) {
		StringBuffer target = new StringBuffer();
		target.append(pkg);
		target.append(".");
		String codePath = module.getCodePath();
		target.append(codePath);
		target.append(".");
		target.append(part.toLowerCase());
		return target.toString();
	}

	/**
	 * 获得指定的java class name
	 * @param tableName
	 * @param string
	 * @return
	 */
	private String getJavaJsClassName(String tableName, String part) {
		//将表名转换为JAVA类名
		String className = StringUtils.convertTableNameToClazzName(tableName);
		return className + StringUtils.convertFirstCharUpperCap(part);
	}
	
	/**
	 * 获取JS Class ID
	 */
	private String getJsClassId(ModuleModel module, String part){
		
		StringBuffer target = new StringBuffer();
		String jsPrefix1 = StringUtils.convertFirstCharUpperCap(jsPrefix);
		target.append(jsPrefix1);
		target.append("_");
		String midJsClassName = StringUtils.convertStringReplacePointToUnderline(module.getCodePath());
	
		target.append(midJsClassName);
		
		if(!part.equals("module")){
			target.append("_" + part);
		}
		String classIdPrefix = "";
		if(!part.equals("view")){
			classIdPrefix = StringUtils.convertFirstCharUpperCap(module.getModuleName()) + StringUtils.convertFirstCharUpperCap(part); 
		}else{
			classIdPrefix = "InitContainer";
		}
		
		target.append("_" + classIdPrefix);
		return target.toString();
	}
	
	/**
	 * 获取JS Class ID
	 */
	private String getJsClassId(ModuleModel module, String tableName, String part){
		
		StringBuffer target = new StringBuffer();
		String jsPrefix1 = StringUtils.convertFirstCharUpperCap(jsPrefix);
		target.append(jsPrefix1);
		target.append("_");
		String midJsClassName = StringUtils.convertStringReplacePointToUnderline(module.getCodePath());

		target.append(midJsClassName);
		
		if(!part.equals("module")){
			target.append("_" + part);
		}
		target.append("_" + StringUtils.convertTableNameToClazzName(tableName) + StringUtils.convertFirstCharUpperCap(part));
		return target.toString();
	}
	
	/**
	 * 获取JS ClassName
	 */
	private String getJsClassName(ModuleModel module, String part){
		
		StringBuffer target = new StringBuffer();
		String jsPrefix1 = StringUtils.convertFirstCharUpperCap(jsPrefix);
		target.append(jsPrefix1);
		target.append(".");
		String midJsClassName = module.getCodePath();
		target.append(midJsClassName);
		
		if(!part.equals("module")){
			target.append("." + part);
		}
		String className = "";
		if(part.equals("controller")) {
			className = StringUtils.convertServiceClassToJsModuleName(module.getServiceCls())+StringUtils.convertFirstCharUpperCap(part);
		}
		if(part.equals("view")) {
			className = "InitContainer";
		}else {
			className = StringUtils.convertServiceClassToJsModuleName(module.getServiceCls())+StringUtils.convertFirstCharUpperCap(part);
		}
		target.append("." + className);
		return target.toString();
	}
	
	/**
	 * 获取JS ModuleClassName
	 */
	private String getJsModuleClassName(ModuleModel module){
		
		StringBuffer target = new StringBuffer();
		
		String moduleClassName = module.getServiceCls();
		
		target.append(moduleClassName);
		
		return target.toString();
	}
	
	/**
	 * 获取JS ClassName
	 */
	private String getJsClassName(ModuleModel module, String tableName, String part){
		
		StringBuffer target = new StringBuffer();
		String jsPrefix1 = StringUtils.convertFirstCharUpperCap(jsPrefix);
		target.append(jsPrefix1);
		target.append(".");
		String midJsClassName = module.getCodePath();
		
		target.append(midJsClassName);
		
		if(!part.equals("module")){
			target.append("." + part);
		}
		target.append("." + StringUtils.convertTableNameToClazzName(tableName) + StringUtils.convertFirstCharUpperCap(part));
		return target.toString();
	}
	/**
	 * 生成JS父文件夹
	 */
	private String createJsFilePath(ModuleModel module, String part){
		StringBuffer target = new StringBuffer();
		target.append(jsModPath);
		target.append("/");
		String midJsFilePath = StringUtils.convertStringReplacePointToSplash(module.getCodePath());
		target.append(midJsFilePath);
		
		if(!part.equals("module")){
			target.append("/" + part);
		}
		
		createFolder(target.toString());
		return target.toString();
	}
	
	/**
	 * 判断指定路径的目录是否存在，不存在则创建
	 */
	private void createFolder(String folderPath){
		
		File filePath = new File(folderPath.toString());
		if(!filePath.exists()){
			filePath.mkdirs();
		}
	}
	
	/**
	 * 获取JS文件路径（父）
	 */
	private String getJsFileAbsName(ModuleModel module, String part){
		StringBuffer target = new StringBuffer(createJsFilePath(module, part));
		target.append("/" + StringUtils.convertServiceClassToJsModuleName(module.getServiceCls()) + StringUtils.convertFirstCharUpperCap(part) + ".js");
		return target.toString();
	}
	
	/**
	 * 获取Module文件路径
	 */
	private String getJsModuleName(ModuleModel module, String part){
		StringBuffer target = new StringBuffer(createJsFilePath(module, part));
		String moduleName = module.getServiceCls();
		String moduleClassName = StringUtils.convertServiceClassToJsModuleName(moduleName);
		target.append("/" +moduleClassName+ ".js");
		return target.toString();
	}
	
	/**
	 * 生成单个Dao
	 * @param module
	 * @throws Exception
	 */
	private void genJavaDao(ModuleModel module) throws Exception{
		String tableNames = module.getTableName();
		if(tableNames == null || tableNames.trim().equals("")){
			return;
		}
		String[] tableNameArray = tableNames.split(",");
		for(String tableName : tableNameArray){
			
			String[] tableArray = tableName.split(":");
			String ds = dataSource;
			
			if(tableArray.length == 2){
				ds = tableArray[0];
				tableName = tableArray[1];
			}
			
			if(tableName.trim().equals("")){
				continue;
			}
			
			//文件类名
			String daoClassName = getJavaJsClassName(tableName, "dao");
			
			//文件夹路径
			String filePath = createJavaFolderPath(module, "dao");
			
			//model名
			String modelClassName = getJavaJsClassName(tableName, "model");
			
			PK pk = DaoTools.getInstance().getPkByTableName(tableName, ds);
			
			//package Name
			String pkgName = getJavaPkgName(module, "dao");
			
			//import list
			List<String> importList = new ArrayList<String>();
			importList.add(getJavaPkgName(module, "model") + "." + getJavaJsClassName(tableName, "model"));
			
			Template template = Velocity.getTemplate(JAVA_DAO_TEMPLATE);
			VelocityContext context = new VelocityContext();
			context.put("daoClassName", daoClassName);
			context.put("modelClassName", modelClassName);
			context.put("pkgName", pkgName);
			context.put("importList", importList);
			context.put("methodSubName", getJavaJsClassName(tableName, ""));
			context.put("moduleName", module.getModuleName());
			context.put("dataSource", ds);
			context.put("pk", pk);
			
			FileWriter fileWriter = new FileWriter(filePath + "/" + daoClassName + ".java");
			template.merge(context, fileWriter);
			fileWriter.close();
		}
	}

	/**
	 * 生成目录结构
	 */
	public void genJavaDirs(ModuleModel module) {

			createJavaFolderPath(module, "");
			createJavaFolderPath(module, "model");
			createJavaFolderPath(module, "dao");
			createJavaFolderPath(module, "service/impl");
			createJavaFolderPath(module, "config/sqlxml");
	}

	/**
	 * 生成Js view 
	 * @throws Exception 
	 * @throws ParseErrorException 
	 * @throws ResourceNotFoundException 
	 */
	public void genJsView(ModuleModel module) throws Exception {
		String filePath = createJsFilePath(module, "view");
		
		String className = getJsClassName(module, "view");
		
		String classId = getJsClassId(module, "view");
		
		String fileName = "InitContainer.js";
		
		Template template = Velocity.getTemplate(JS_VIEW_TEMPLATE);
		VelocityContext context = new VelocityContext();
		context.put("jsClassName", className);
		context.put("jsClassId", classId);
		FileWriter fileWriter = new FileWriter(filePath + "/" + fileName);
		template.merge(context, fileWriter);
		fileWriter.close();
	}

	public boolean isJsFilePathExist(ModuleModel module){
		StringBuffer target = new StringBuffer();
		target.append(jsModPath);
		target.append("/");
		String midJsFilePath = StringUtils.convertStringReplacePointToSplash(module.getCodePath());
		
		target.append(midJsFilePath);
		
		
		return new File(target.toString()).exists();
	}
	
	private boolean isJavaFilePathExist(ModuleModel module) {

		StringBuffer target = new StringBuffer();
		target.append(javaModPath);
		target.append("/");
		String pkgPath = StringUtils.convertStringReplacePointToSplash(pkg);
		target.append(pkgPath);
		target.append("/");
		String midFilePath = StringUtils.convertStringReplacePointToSplash(module.getCodePath());
		
		target.append(midFilePath);
		
		target.append("/");
		
		return new File(target.toString()).exists();
	}
	
	/**
	 * 生成Js代码
	 * @param task
	 * @throws Exception 
	 */
	public void genJsCode(Task task) throws Exception {
		for(ModuleModel module : moduleList){
			if(isJsFilePathExist(module) && !isCover){
				System.out.println("模块" + module.getModuleName() + "(" + module.getModuleText() + ")" + "Js代码已存在");
				continue;
			}
			genJsDirs(module);
	    	genJsController(module);
	    	genJsModel(module);
	    	genJsModule(module);
	    	genJsStore(module);
	    	genJsView(module);
	    	System.out.println("模块" + module.getModuleName() + "(" + module.getModuleText() + ")" + "Js代码生成成功");
		}
	}

	/**
	 * 生成Java代码
	 * @param task 
	 * @throws Exception
	 */
	public void genJavaCode(Task task) throws Exception {
		for(ModuleModel module : moduleList){
			if(isJavaFilePathExist(module) && !isCover){
				System.out.println("模块" + module.getModuleName() + "(" + module.getModuleText() + ")" + "Java代码已存在");
				continue;
			}
			genJavaDirs(module);
			genJavaDao(module);
			genJavaModel(module);
			genJavaService(module);
			genJavaSqlXml(module);
			System.out.println("模块" + module.getModuleName() + "(" + module.getModuleText() + ")" + "Java代码生成成功");
		}
	}
}
